package cn.hsw.platform.service.impl;

import cn.hsw.platform.core.api.SnowFlakeApi;
import cn.hsw.platform.core.doc.util.AuthUtil;
import cn.hsw.platform.core.base.BaseServiceImpl;
import cn.hsw.platform.core.util.Validator;
import cn.hsw.platform.model.PermissionModel;
import cn.hsw.platform.model.RoleModel;
import cn.hsw.platform.model.RolePermissionCenter;
import cn.hsw.platform.model.UserRoleCenter;
import cn.hsw.platform.repository.RolePermissionCenterRepository;
import cn.hsw.platform.repository.RoleRepository;
import cn.hsw.platform.repository.UserRoleCenterRepository;
import cn.hsw.platform.service.PermissionService;
import cn.hsw.platform.service.RoleService;
import cn.hsw.platform.vo.RolePermissionVO;
import cn.hsw.platform.vo.RoleVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @author 李子木
 * @date 2020-11-10
 */
@Service
public class RoleServiceImpl extends BaseServiceImpl<RoleRepository,RoleModel,Long> implements RoleService {

    @Autowired
    SnowFlakeApi api;

    @Autowired
    UserRoleCenterRepository userRoleCenterRepository;

    @Autowired
    PermissionService permissionService;

    @Autowired
    RolePermissionCenterRepository rolePermissionCenterRepository;

    @Autowired
    AuthUtil authUtil;

    @Override
    public RoleModel findByCode(String code) {
        return getRepository().findByCode(code);
    }

    @Override
    public void edit(RoleModel roleModel, RoleVO roleVO) {
        if(Validator.isNotNull(roleVO.getName())){
            roleModel.setName(roleVO.getName());
        }
        if(Validator.isNotNull(roleVO.getRemark())){
            roleModel.setRemark(roleVO.getRemark());
        }
        this.save(roleModel);

        authUtil.clearRolePidCache(roleModel.getPid());
    }

    @Override
    public void add(RoleModel roleModel) {

        //生成code
        Long code = Validator.validateApiSuccess(api.generate());

        roleModel.setCode(code.toString());

        this.save(roleModel);

    }

    @Override
    public void delete(Long pid) {
        super.delete(pid);

        authUtil.clearRolePidCache(pid);
    }

    @Override
    public boolean bind(Long userPid, Long rolePid) {
        RoleModel roleModel = this.findById(rolePid);
        Validator.validateNotNull(roleModel,"操作非法,当前角色不存在");

        UserRoleCenter userRoleCenter = new UserRoleCenter();
        userRoleCenter.setUserPid(userPid);
        userRoleCenter.setRolePid(rolePid);

        userRoleCenter = userRoleCenterRepository.save(userRoleCenter);

        return Validator.isNotEmpty(userRoleCenter.getPid());
    }

    @Override
    public void unBind(Long userPid) {
        userRoleCenterRepository.deleteByUserPid(userPid);
    }

    @Override
    public boolean validateRoleHaveUser(Long pid) {

        return userRoleCenterRepository.countByRolePid(pid)>0;
    }

    @Override
    public RolePermissionVO auth(Long rolePid) {
        List<RolePermissionCenter> rolePermissionCenterList = rolePermissionCenterRepository.findByRolePid(rolePid);

        List<Long> list = rolePermissionCenterList.stream().map(RolePermissionCenter::getPermissionPid).collect(Collectors.toList());
        RolePermissionVO rolePermissionVO = new RolePermissionVO();
        rolePermissionVO.setRolePid(rolePid);
        rolePermissionVO.setPermissionPids(list);
        return rolePermissionVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void authorization(RolePermissionVO params) {
        RoleModel roleModel = this.findById(params.getRolePid());
        Validator.validateNotNull(roleModel,"操作非法,当前角色不存在");

        List<Long> permissionList = params.getPermissionPids();

        List<String> roleCodeList = new ArrayList<>();
        List<RolePermissionCenter> insList = new ArrayList<>();
        for (Long permissionPid:permissionList){
            PermissionModel permissionModel = permissionService.findById(permissionPid);
            Validator.validateNotNull(permissionModel,"操作非法,权限ID不存在");
            RolePermissionCenter rolePermissionCenter = new RolePermissionCenter();
            rolePermissionCenter.setRolePid(params.getRolePid());
            rolePermissionCenter.setPermissionPid(permissionPid);
            insList.add(rolePermissionCenter);
            roleCodeList.add(permissionModel.getCode());
        }
        rolePermissionCenterRepository.deleteByRolePid(params.getRolePid());
        rolePermissionCenterRepository.saveAll(insList);


        authUtil.setAuthRoleCache(params.getRolePid(),roleCodeList);
    }

    @Override
    public List<RoleModel> findByUserPid(Long userPid) {
        List<RoleModel> roleList = new ArrayList<>();

        List<UserRoleCenter> list = userRoleCenterRepository.findByUserPid(userPid);
        for (UserRoleCenter userRoleCenter:list){
            roleList.add(this.findById(userRoleCenter.getRolePid()));
        }
        return roleList;
    }

    @Override
    public List<Long> findRolePidByUserPid(Long userPid) {
        return userRoleCenterRepository.findRolePidByUserPid(userPid);
    }

    @Override
    public List<String> findPermissionCodeByRolePid(Long rolePid) {

        List<RolePermissionCenter> rolePermissionCenterList = rolePermissionCenterRepository.findByRolePid(rolePid);

        List<Long> idList = rolePermissionCenterList.stream().map(RolePermissionCenter::getPermissionPid).collect(Collectors.toList());

        List<PermissionModel> permissionList = permissionService.findAll(idList);

        return permissionList.stream().map(PermissionModel::getCode).collect(Collectors.toList());
    }
}
